package mybox.engine.rundfeder;

import static java.lang.Math.PI;
import static java.lang.Math.cos;
import static java.lang.Math.sin;
import mybox.engine.Figur;
import mybox.engine.File4Qcad;
import mybox.engine.Line;
import mybox.engine.QVector;

public class Ukulele implements Figur {

	File4Qcad file4qcad;
	public Kurve kurve = new Kurve();
	public Kurve cutLine = new Kurve();
	double startPhi;	
	double radius;
	double gesamtWinkel;	
	int clockwise;
	QVector lastEndPoint;
	Sector sector;
	int kruemmungswechsel;
	
	public Ukulele(File4Qcad file4qcad, QVector start) {
		this.file4qcad=file4qcad;
		Line[] linearr = new Line[1];
		QVector endLine = new QVector(start.x,start.y+19.826-0.0595017);
		linearr[0] = new Line(file4qcad,start,endLine);
		kurve.addLineArr(linearr);
		
		startPhi=PI;radius=60;gesamtWinkel=45*PI/180;clockwise=1;lastEndPoint=endLine;
		sector = addSector2Kurve();
		
		kruemmungswechsel=0;
		startPhi=sector.endPhi;radius=70;gesamtWinkel=45*PI/180;lastEndPoint=sector.end;clockwise=1;	
		sector = addSector2Kurve();
		
		kruemmungswechsel=0;
		startPhi=sector.endPhi;radius=40;gesamtWinkel=22.5*PI/180;lastEndPoint=sector.end;clockwise=1;
		sector = addSector2Kurve();		
		
		kruemmungswechsel=0;
		lastEndPoint=addLine(file4qcad, kurve,sector.end, sector.endPhi-clockwise*PI/2,20);
		
		
		kruemmungswechsel=1;
		startPhi=sector.endPhi+PI;radius=15;gesamtWinkel=45*PI/180;clockwise=-1;
		sector = addSector2Kuve(file4qcad,kurve,startPhi,radius,gesamtWinkel,clockwise,lastEndPoint);
		
		lastEndPoint=addLine(file4qcad, kurve,sector.end, sector.endPhi-clockwise*PI/2,80);
		
		
		startPhi=sector.endPhi+PI;radius=80;gesamtWinkel=90*PI/180;clockwise=1;
		sector = addSector2Kuve(file4qcad,kurve,startPhi,radius,gesamtWinkel,clockwise,lastEndPoint);
		
		startPhi=sector.endPhi;radius=155;gesamtWinkel=22.5*PI/180;clockwise=1;lastEndPoint=sector.end;
		sector = addSector2Kuve(file4qcad,kurve,startPhi,radius,gesamtWinkel,clockwise,lastEndPoint);
		
		System.out.println("sector.endPhi="+(sector.endPhi-2*PI));
		//Mitte		
		startPhi=sector.endPhi;radius=155;gesamtWinkel=22.5*PI/180;clockwise=1;lastEndPoint=sector.end;
		sector = addSector2Kuve(file4qcad,kurve,startPhi,radius,gesamtWinkel,clockwise,lastEndPoint);
		
		
		startPhi=sector.endPhi;radius=80;gesamtWinkel=90*PI/180;clockwise=1;lastEndPoint=sector.end;
		sector = addSector2Kuve(file4qcad,kurve,startPhi,radius,gesamtWinkel,clockwise,lastEndPoint);
				
		lastEndPoint=addLine(file4qcad, kurve,sector.end, sector.endPhi-clockwise*PI/2,80);
		
		
		startPhi=sector.endPhi+PI;radius=15;gesamtWinkel=45*PI/180;clockwise=-1;
		sector = addSector2Kuve(file4qcad,kurve,startPhi,radius,gesamtWinkel,clockwise,lastEndPoint);
		
		lastEndPoint=addLine(file4qcad, kurve,sector.end, sector.endPhi-clockwise*PI/2,20);
		
		
		startPhi=sector.endPhi+PI;radius=40;gesamtWinkel=22.5*PI/180;clockwise=1;
		sector = addSector2Kuve(file4qcad,kurve,startPhi,radius,gesamtWinkel,clockwise,lastEndPoint);
		
		startPhi=sector.endPhi;radius=70;gesamtWinkel=PI/4;lastEndPoint=sector.end;clockwise=1;	
		sector = addSector2Kuve(file4qcad,kurve,startPhi,radius,gesamtWinkel,clockwise,lastEndPoint);
	
		startPhi=sector.endPhi;	radius=60;gesamtWinkel=PI/4;clockwise=1;lastEndPoint=sector.end;
		sector = addSector2Kuve(file4qcad,kurve,startPhi,radius,gesamtWinkel,clockwise,lastEndPoint);
		
		lastEndPoint=addLine(file4qcad, kurve,sector.end, sector.endPhi-clockwise*PI/2,19.826-0.0595017);
		
		
	}
	
	public void kreisAbschlagen(double radiusHohl, double radiusVoll) {
	   	
	}
	
	public Schnittpunkt findeForwardSchnittPunkt(Schnittpunkt from, double radius) {
		Schnittpunkt to;
		
		boolean schnittpunktFound=false;		
		int testIdxFrom=from.kurvenIdx;
		int testIdxTo=kurve.size()-1;
		int testIdx=-1;
		
		while (!schnittpunktFound && testIdxFrom<testIdxTo) {			
			testIdx=(testIdxFrom+testIdxTo)/2;
			int dist = closeFarFound(testIdx, from, radius);			
			if (dist==-1) 
				testIdxFrom=testIdx+1;
			if (dist==1)  
				testIdxTo=testIdx;
			if (dist==0)  
				schnittpunktFound=true;
		}
		System.out.println("Debug testIdx="+testIdx);
		System.out.println("Debug zielSegment="+kurve.get(testIdx).toString());
		System.out.println("Debug fromPunkt="+from);
		
		to=new Schnittpunkt(testIdx,new QVector(0,0));		
		if (testIdx==from.kurvenIdx) {
			//Richtungsvektor
			double xv=kurve.get(testIdx).end.x-kurve.get(testIdx).begin.x;
			double yv=kurve.get(testIdx).end.y-kurve.get(testIdx).begin.y;
			double v_length=Math.sqrt(xv*xv+yv*yv);
			double xv_norm=xv/v_length;
			double yv_norm=yv/v_length;
			to.ort.x=from.ort.x+xv_norm*radius;
			to.ort.y=from.ort.y+yv_norm*radius;			
		} else {		
			double rawDiffClose=QVector.diff(from.ort, kurve.get(testIdx).begin).length();
			double rawDiffFar=QVector.diff(from.ort, kurve.get(testIdx).end).length();
		
			//Berechnet die mittlere Stelle zwischen Anfang und Endpunkt 
			//die dem Radius entspricht radius = close*lambda + far*(1-lambda)
			double lambda=(radius-rawDiffFar)/(rawDiffClose-rawDiffFar);
			to.ort.x=kurve.get(testIdx).begin.x*lambda+kurve.get(testIdx).end.x*(1-lambda);
			to.ort.y=kurve.get(testIdx).begin.y*lambda+kurve.get(testIdx).end.y*(1-lambda);
		}
				
		return to;
	}
	
	public int closeFarFound(int testIdx, Schnittpunkt from, double radius) {
		int retVal=-2;		
		double rawDiffClose=QVector.diff(from.ort, kurve.get(testIdx).begin).length();
		double rawDiffFar=QVector.diff(from.ort, kurve.get(testIdx).end).length();
		
		if (rawDiffClose<radius && rawDiffFar<radius) retVal=-1;
		if (rawDiffClose>radius && rawDiffFar>radius) retVal=1;
		if (rawDiffClose<=radius && rawDiffFar>=radius) retVal=0;
		
		return retVal;
	}
	
	public QVector addLine(File4Qcad file4qcad, Kurve kurve, QVector start, double phi, double length) {
		Line[] linearr = new Line[1];
		QVector endLine = new QVector(start.x+length*cos(phi),start.y+length*sin(phi));
		linearr[0] = new Line(file4qcad,start,endLine);		
		kurve.addLineArr(linearr);		
		return endLine;		
	}
	
	public Sector addSector2Kurve() {
		return addSector2Kuve(file4qcad,kurve,startPhi,radius,gesamtWinkel,clockwise,lastEndPoint);
	}
	
	public Sector addSector2Kuve(File4Qcad file4qcad, Kurve kurve, double startPhi,double radius,double gesamtWinkel,int clockwise,QVector lastEndPoint) {
		Sector sector = new Sector(
    			file4qcad, 
    			lastEndPoint, 
    			startPhi, 				              
    			radius, 
    			gesamtWinkel,
    			clockwise);
		kurve.addSector(sector);
		return sector;
	}
	
	@Override
	public void draw() {
		kurve.draw();		
	}
	
	public void drawCutline() {
		cutLine.draw();
	}

}
